package com.google.code.swingonfire.showcase.component.page;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JPanel;

import com.google.code.swingonfire.border.ShadowBorder;
import com.google.code.swingonfire.component.JBorderPanel;
import com.google.code.swingonfire.component.page.AbstractJPageComponent;
import com.google.code.swingonfire.component.page.JPageComponentAnimation;
import com.google.code.swingonfire.component.page.JPageComponentAnimations;
import com.google.code.swingonfire.showcase.TitlePanel;
import com.google.code.swingonfire.showcase.utils.BooleanParameterDefinition;
import com.google.code.swingonfire.showcase.utils.ComboBoxParameterDefinition;
import com.google.code.swingonfire.showcase.utils.DoubleSliderParameterDefinition;
import com.google.code.swingonfire.showcase.utils.ParameterPanel;
import com.google.code.swingonfire.utility.interpolation.Interpolation;
import com.google.code.swingonfire.utility.interpolation.Interpolations;

public abstract class AbstractJPageComponentShowcase<COMPONENT_TYPE extends AbstractJPageComponent> extends JPanel implements ActionListener
{

    private static final long serialVersionUID = -4380340026221459617L;

    private final COMPONENT_TYPE pageComponent;
    private final ParameterPanel parameterPanel;

    public AbstractJPageComponentShowcase()
    {
        super(new BorderLayout());

        pageComponent = createPageComponent();
        
        pageComponent.setBackground(Color.BLACK);
        pageComponent.setOpaque(true);

        JPanel controllerPanel = new JPanel(new BorderLayout());

        parameterPanel =
            new ParameterPanel(new ComboBoxParameterDefinition("Animation",
                JPageComponentAnimations.class.getSimpleName() + ".horizontal()",

                new ComboBoxParameterDefinition.Option(JPageComponentAnimations.class.getSimpleName() + ".fade()",
                    JPageComponentAnimations.fade()), //
                new ComboBoxParameterDefinition.Option(JPageComponentAnimations.class.getSimpleName() + ".shrink()",
                    JPageComponentAnimations.shrink()), //
                new ComboBoxParameterDefinition.Option(JPageComponentAnimations.class.getSimpleName()
                    + ".horizontalFade()", JPageComponentAnimations.horizontalFade()), //
                new ComboBoxParameterDefinition.Option(JPageComponentAnimations.class.getSimpleName()
                    + ".verticalFade()", JPageComponentAnimations.verticalFade()), //
                new ComboBoxParameterDefinition.Option(JPageComponentAnimations.class.getSimpleName()
                    + ".horizontalFadeAndShrink()", JPageComponentAnimations.horizontalFadeAndShrink()), //
                new ComboBoxParameterDefinition.Option(JPageComponentAnimations.class.getSimpleName()
                    + ".verticalFadeAndShrink()", JPageComponentAnimations.verticalFadeAndShrink()), //
                new ComboBoxParameterDefinition.Option(
                    JPageComponentAnimations.class.getSimpleName() + ".horizontal()",
                    JPageComponentAnimations.horizontal()), //
                new ComboBoxParameterDefinition.Option(JPageComponentAnimations.class.getSimpleName() + ".vertical()",
                    JPageComponentAnimations.vertical()), //
                new ComboBoxParameterDefinition.Option(JPageComponentAnimations.class.getSimpleName() + ".rotateTop()",
                    JPageComponentAnimations.rotateTop()), //
                new ComboBoxParameterDefinition.Option(JPageComponentAnimations.class.getSimpleName()
                    + ".rotateBottom()", JPageComponentAnimations.rotateBottom()), //
                new ComboBoxParameterDefinition.Option(
                    JPageComponentAnimations.class.getSimpleName() + ".rotateLeft()",
                    JPageComponentAnimations.rotateLeft()), //
                new ComboBoxParameterDefinition.Option(JPageComponentAnimations.class.getSimpleName()
                    + ".rotateRight()", JPageComponentAnimations.rotateRight()), //
                new ComboBoxParameterDefinition.Option(JPageComponentAnimations.class.getSimpleName() + ".newspaper()",
                    JPageComponentAnimations.newspaper())),

            new ComboBoxParameterDefinition("Interpolation", Interpolations.class.getSimpleName() + ".accurate()",
                new ComboBoxParameterDefinition.Option(Interpolations.class.getSimpleName() + ".accelerating()",
                    Interpolations.accelerating()), //
                new ComboBoxParameterDefinition.Option(Interpolations.class.getSimpleName() + ".slowing()",
                    Interpolations.slowing()), //
                new ComboBoxParameterDefinition.Option(Interpolations.class.getSimpleName() + ".accurate()",
                    Interpolations.accurate()), //
                new ComboBoxParameterDefinition.Option(Interpolations.class.getSimpleName() + ".doubtful()",
                    Interpolations.doubtful()), //
                new ComboBoxParameterDefinition.Option(Interpolations.class.getSimpleName() + ".soft()",
                    Interpolations.soft()), //
                new ComboBoxParameterDefinition.Option(Interpolations.class.getSimpleName() + ".toon()",
                    Interpolations.toon())),

            new BooleanParameterDefinition("Animate", "Animation enabled", true), new DoubleSliderParameterDefinition(
                "Duration", 0, 0.5, 5, 0.5, 0.05, "%,.1fs"));

        parameterPanel.setOpaque(true);
        parameterPanel.setBackground(Color.WHITE);
        parameterPanel.addActionListener(this);

        controllerPanel.add(createNavigationPanel(), BorderLayout.NORTH);
        controllerPanel.add(parameterPanel, BorderLayout.CENTER);

        add(new JBorderPanel(createTitlePanel(), ShadowBorder.create()), BorderLayout.NORTH);
        add(new JBorderPanel(pageComponent, ShadowBorder.create()), BorderLayout.CENTER);
        add(new JBorderPanel(controllerPanel, ShadowBorder.create()), BorderLayout.SOUTH);
    }

    protected abstract TitlePanel createTitlePanel();

    protected abstract COMPONENT_TYPE createPageComponent();

    public COMPONENT_TYPE getPageComponent()
    {
        return pageComponent;
    }
    
    protected abstract JPanel createNavigationPanel();

    /**
     * {@inheritDoc}
     */
    @Override
    public void actionPerformed(ActionEvent e)
    {
        pageComponent.setAnimation((JPageComponentAnimation) parameterPanel.getParameter("Animation"));
        pageComponent.setInterpolation((Interpolation) parameterPanel.getParameter("Interpolation"));
        pageComponent.setAnimationEnabled((Boolean) parameterPanel.getParameter("Animate"));
        pageComponent.setAnimationDuration((Double) parameterPanel.getParameter("Duration"));
    }

}
